﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PacoToolKit.Format
{
    /// <summary>
    /// 格式化工具
    /// </summary>
    public class Formater
    {
        #region 类型转换
        /// <summary>
        /// 把任意的变量转换成字符串，如果是null或者DBNull.Value，返回String.Empty
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>字符串，至少是String.Empty</returns>
        public static string ToString(object _obj)
        {
            string m_Result = String.Empty;

            if (_obj == DBNull.Value || _obj == null)
            {
                m_Result = String.Empty;
            }
            else
            {
                m_Result = Convert.ToString(_obj);
            }

            return m_Result;
        }

        /// <summary>
        /// 把任意的变量转换成整形，如果该变量不能转换成整形，返回0
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>整形，至少是0</returns>
        public static int ToInt32(object _obj)
        {
            int m_Result = 0;

            try
            {
                m_Result = Convert.ToInt32(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        ///  把任意的变量转换成长整形，如果该变量不能转换成长整形，返回0
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>整形，至少是0</returns>
        public static long ToInt64(object _obj)
        {
            long m_Result = 0;

            try
            {
                m_Result = Convert.ToInt64(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        ///  把任意的变量转换成短整形，如果该变量不能转换成短整形，返回0
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>整形，至少是0</returns>
        public static short ToInt16(object _obj)
        {
            short m_Result = 0;

            try
            {
                m_Result = Convert.ToInt16(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        ///  把任意的变量转换成字节，如果该变量不能转换成字节，返回0
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>整形，至少是0</returns>
        public static byte ToByte(object _obj)
        {
            byte m_Result = 0;

            try
            {
                m_Result = Convert.ToByte(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        /// 把任意的变量转换为double形，如果该变量不能转换为double,返回0
        /// </summary>
        /// <param name="_obj"></param>
        /// <returns></returns>
        public static double ToDouble(object _obj)
        {
            Double m_Result = 0;

            try
            {
                m_Result = Convert.ToDouble(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        /// 把任意的变量转换为decimal形，如果该变量不能转换为decimal,返回0
        /// </summary>
        /// <param name="_obj"></param>
        /// <returns></returns>
        public static decimal ToDecimal(object _obj)
        {
            decimal m_Result = 0;

            try
            {
                m_Result = Convert.ToDecimal(_obj);
            }
            catch (Exception)
            {
                m_Result = 0;
            }

            return m_Result;
        }

        /// <summary>
        /// 把任意的变量装换成布尔，如果该变量不能转换成布尔，返回false
        /// </summary>
        /// <param name="_obj">任意变量</param>
        /// <returns>布尔，至少是false</returns>
        public static bool ToBoolean(object _obj)
        {
            bool m_Result = false;

            try
            {
                m_Result = Convert.ToBoolean(_obj);
            }
            catch (Exception)
            {
                m_Result = false;
            }

            return m_Result;
        }

        /// <summary>
        /// 时间戳转为C#格式时间
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        public static DateTime StampToDateTime(string timeStamp)
        {
            DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);

            return dateTimeStart.Add(toNow);
        }

        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static int DateTimeToStamp(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        #endregion

        #region 报文相关
        /// <summary>
        /// 在报文帧加入空白，方便阅读
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string AddSpace(string msg)
        {
            StringBuilder sb = new StringBuilder();
            int len = msg.Length / 2;
            for (int i = 0; i < len; i++)
            {
                sb.Append(msg.Substring(i * 2, 2) + " ");
            }
            return sb.ToString();
        }
        /// <summary>
        /// 移除0x68起始帧 之前所有内容
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string RemoveBeforeFirst68(string msg)
        {
            int len = msg.Length;
            string temp = "";
            for (int i = 0; i < len - 1; i++)
            {
                if ((msg.Substring(i, 2).Equals("68")))
                {
                    temp = msg.Remove(0, i);
                    break;
                }
                else
                {
                    temp = msg;
                }
            }
            return temp;
        }
        /// <summary>
        /// 十进制字符串转为二进制字符串
        /// </summary>
        /// <param name="DEC"></param>
        /// <returns></returns>
        public static string DECtoBIN(string DEC)
        {
            return Convert.ToString(int.Parse(DEC), 2);
        }
        /// <summary>
        /// 十进制字串转换为二进制字串，并且保留固定位数的0
        /// </summary>
        /// <param name="DEC"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string DECtoBIN(string DEC, int length)
        {
            //override
            string bin_str = Convert.ToString(int.Parse(DEC), 2);
            if (length < bin_str.Length) { return bin_str; }
            else
            {
                int bin_len = bin_str.Length;
                for (int i = 0; i < length - bin_len; i++)
                {
                    bin_str = bin_str.Insert(0, "0");
                }
                return bin_str;
            }
        }

        /// <summary>
        /// 十进制字符串转为十六进制字符串(会自动省略掉头部的0)
        /// </summary>
        /// <param name="DEC"></param>
        /// <returns></returns>
        public static string DECtoHEX(string DEC)
        {
            return Convert.ToString(int.Parse(DEC), 16);
        }
        /// <summary>
        /// 十进制字符串转为固定位数的二进制字符串
        /// </summary>
        /// <param name="DEC">十进制字串</param>
        /// <param name="length">目标十六进制的位数</param>
        /// <returns></returns>
        public static string DECtoHEX(string DEC, int length)
        {
            //override
            string hex_str;
            try
            {
                if(length==4)
                {
                    //双字节
                    hex_str = Convert.ToString(ushort.Parse(DEC), 16);
                }
                else if(length==2)
                {
                    hex_str = Convert.ToString(byte.Parse(DEC), 16);
                }
                else
                {
                    hex_str = Convert.ToString(UInt32.Parse(DEC), 16);
                }
            }
            catch (System.ArgumentException e)
            {
                throw e;
            }
            catch (System.OverflowException e)
            {
                throw e;
            }
            catch (System.FormatException e)
            {
                throw e;
            }
            if (length < hex_str.Length) { return hex_str.ToUpper(); }
            else
            {
                int bin_len = hex_str.Length;
                for (int i = 0; i < length - bin_len; i++)
                {
                    hex_str = hex_str.Insert(0, "0");
                }
                return hex_str.ToUpper();
            }
        }

        /// <summary>
        /// 补齐数据长度(补零),在头部补
        /// </summary>
        /// <param name="source"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string AdjustLengthHead(string source, int length)
        {
            if (length < source.Length)
                return source;
            else
            {
                int bin_len = source.Length;
                for (int i = 0; i < length - bin_len; i++)
                {
                    source = source.Insert(0, "0");
                }
                return source;
            }
        }
        /// <summary>
        /// 补齐数据长度(补零),在尾部补
        /// </summary>
        /// <param name="source"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string AdjustLengthBottom(string source, int length)
        {
            if (length < source.Length)
                return source;
            else
            {
                int bin_len = source.Length;
                for (int i = 0; i < length - bin_len; i++)
                {
                    source += "0";
                }
                return source;
            }
        }


        /// <summary>
        /// 二进制字符串转为整形字符串
        /// </summary>
        /// <param name="BIN"></param>
        /// <returns></returns>
        public static string BINtoDEC(string BIN)
        {
            return Convert.ToInt32(BIN, 2).ToString();
        }
        /// <summary>
        /// 16进制字符串转为整形字符串
        /// </summary>
        /// <param name="HEX"></param>
        /// <returns></returns>
        public static string HEXtoDEC(string HEX)
        {
            return Convert.ToInt64(HEX, 16).ToString();
        }

        /// <summary>
        /// 双字节16进制字符串转为有符号整形字符串
        /// </summary>
        /// <param name="HEX"></param>
        /// <returns></returns>
        public static string TwoByteHEXtoDEC(string TwoByteHEX)
        {
            return Convert.ToInt16(TwoByteHEX, 16).ToString();
        }

        /// <summary>
        /// 4字节16进制字符串转为有符号整形字符串
        /// </summary>
        /// <param name="TwoByteHEX"></param>
        /// <returns></returns>
        public static string FourByteHEXtoDEC(string TwoByteHEX)
        {
            return Convert.ToInt32(TwoByteHEX, 16).ToString();
        }

        /// <summary>
        /// 将16进制字符串高低字节对换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReverseHexString(string str)
        {
            char[] buff = new char[str.Length];
            for (int i = 0; i < str.Length; i += 2)
            {
                buff[i] = str[str.Length - i - 2];
                buff[i + 1] = str[str.Length - 1 - i];
            }
            string s = new string(buff);
            return s;
        }

        public static string ReverseHexStringHighLow(string str)
        {
            int len = str.Length;
            string high = str.Substring(0, len / 2);
            string low = str.Substring(len / 2, len / 2);
            return low + high;
        }

        public static string ReverseString(string input)
        {
            if (String.IsNullOrEmpty(input))
            {
                return input;
            }

            char[] charArray = input.ToCharArray();
            Array.Reverse(charArray);
            return new String(charArray);
        }

        /// <summary>
        /// 将16进制字符转化成byte[]，顺序从由高到低转为由低到高
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string str)
        {
            str = str.Replace(" ", "");
            str = str.Trim();//清除空白
            int len = str.Length / 2;
            byte[] bytes = new byte[len];
            for (int i = 0; i < len; i++)
            {
                string tem;
                tem = str.Substring(str.Length - (2 * (i + 1)), 2);
                bytes[i] = Convert.ToByte(tem, 16);//16进制
            }
            return bytes;
        }

        /// <summary>
        /// 将16进制字符转化成byte[]，顺序不变
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytesKeep(string str)
        {
            str = str.Replace(" ", "");
            str = str.Trim();//清除空白
            int len = str.Length / 2;
            byte[] bytes = new byte[len];
            for (int i = 0; i < len; i++)
            {
                string tem;
                tem = str.Substring(i * 2, 2);
                bytes[i] = Convert.ToByte(tem, 16);//16进制
            }
            return bytes;
        }

        /// <summary>
        /// 4字节Hex转换为float
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static float HexStringToFloat(string str)
        {
            byte[] bytes = HexStringToBytes(str);//高低对调
            return BitConverter.ToSingle(bytes, 0);
        }

        /// <summary>
        /// 8字节Hex转换为double
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static double HexStringToDouble(string str)
        {
            byte[] bytes = HexStringToBytes(str);//高低对调
            return BitConverter.ToDouble(bytes, 0);
        }

        /// <summary>
        /// 转化bytes成16进制的字符
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }

        /// <summary>
        /// 转换字符串为ASCLL码的十六进制字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string StringToASCLLHexStr(string str)
        {
            string temp = "";
            char[] charbuff = new char[str.Length];
            for (int i = 0; i < str.Length; i++)
            {
                temp += Convert.ToInt32(str[i]).ToString("X");
            }
            return temp;
        }

        ///// <summary>
        ///// 16进制字符串转对应ASCII字符串:
        ///// </summary>
        ///// <param name="str"></param>
        ///// <returns></returns>
        //public static string ASCLLHexStrToString(string hex_str)
        //{
        //    StringBuilder temp = new StringBuilder();
        //    byte[] buff = new byte[hex_str.Length / 2];
        //    for (int i = 0; i < buff.Length; i++)
        //    {
        //        temp.Append(((char)buff[i]).ToString());
        //    }
        //    return temp.ToString();
        //}

        /// <summary>
        /// 16进制bytes转对应ASCII字符串:
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ASCLLHexBytesToString(byte[] bytes)
        {
            StringBuilder temp = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                temp.Append(((char)bytes[i]).ToString());
            }
            return temp.ToString();
        }

        public static byte CalcCSCode(byte[] bytes)
        {
            int temp = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                temp = temp + Convert.ToInt32(bytes[i]);
            }
            return Convert.ToByte(temp % 256);
        }



        public static string CalcCSCode(string str)
        {
            return CalcCSCode(HexStringToBytesKeep(str)).ToString("X2");
        }


        /// <summary>
        /// [停用:不能溢出截断]每个字节加0x33
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte[] Plus0X33(byte[] bytes)
        {
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = Convert.ToByte(bytes[i] + 0x33);//发现结果溢出会抛出异常
            }
            return bytes;
        }

        /// <summary>
        /// 每个字节加0x33
        /// </summary>
        /// <param name="bytes">字节列表</param>
        /// <returns>增加0x33后的字符串形式结果</returns>
        public static string Plus0x33(byte[] bytes)
        {
            string temp = string.Empty;
            foreach (byte b in bytes)
            {
                string t = Convert.ToString(b + 0x33, 16);
                if (t.Length == 3) { t = t.Substring(1, 2); }
                temp += t;
            }
            return temp;
        }

        /// <summary>
        /// 每个字节减去0x33
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte[] Subtract0X33(byte[] bytes)
        {
            for (int i = 0; i < bytes.Length; i++)
            {
                if (bytes[i] >= 0x33)
                {
                    bytes[i] = Convert.ToByte(bytes[i] - 0x33);
                }
                //溢出
                else
                {
                    int temp = bytes[i] - 0x33;
                    temp += 256;
                    bytes[i] = Convert.ToByte(temp);
                }
            }
            return bytes;
        }

        /// <summary>
        /// C# CRC16校验算法 -输出是包含原有数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] crc16(byte[] data)
        {
            byte[] temdata = new byte[data.Length + 2];
            int xda, xdapoly;
            int i, j, xdabit;
            xda = 0xFFFF;
            xdapoly = 0xA001;
            for (i = 0; i < data.Length; i++)
            {
                xda ^= data[i];
                for (j = 0; j < 8; j++)
                {
                    xdabit = (int)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                        xda ^= xdapoly;
                }
            }
            Array.Copy(data, 0, temdata, 0, data.Length);
            temdata[temdata.Length - 2] = (byte)(xda & 0xFF);
            temdata[temdata.Length - 1] = (byte)(xda >> 8);
            return temdata;
        }

        /// <summary>
        /// CRC16校验算法
        /// </summary>
        /// <param name="data"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static byte[] crc16(byte[] data, int len)
        {
            byte[] temdata = new byte[2];
            int xda, xdapoly;
            int i, j, xdabit;
            xda = 0xFFFF;
            xdapoly = 0xA001;
            for (i = 0; i < len; i++)
            {
                xda ^= data[i];
                for (j = 0; j < 8; j++)
                {
                    xdabit = (int)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                        xda ^= xdapoly;
                }
            }
            temdata[0] = (byte)(xda & 0xFF);
            temdata[1] = (byte)(xda >> 8);
            return temdata;
        }
        #endregion

    }
}
